package top.lingkang.finaloauth2.server.controller;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import top.lingkang.finaloauth2.entity.OAuth2AccessToken;
import top.lingkang.finaloauth2.server.auth.AuthServerGetToken;
import top.lingkang.finaloauth2.server.auth.AuthServerResponse;
import top.lingkang.finaloauth2.server.auth.AuthorizationMode;
import top.lingkang.finaloauth2.server.error.AuthServerException;
import top.lingkang.finaloauth2.server.error.AuthServerExceptionHandler;
import top.lingkang.finaloauth2.server.store.TokenStore;
import top.lingkang.finaloauth2.utils.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author lingkang
 * Created by 2022/3/23
 */
@RestController
public class AuthServerController extends SimpleUrlHandlerMapping {
    private static final Log log = LogFactory.getLog(AuthServerController.class);
    @Autowired
    private AuthorizationMode authorizationMode;
    @Autowired
    private AuthServerExceptionHandler authServerExceptionHandler;
    @Autowired
    private AuthServerResponse authServerResponse;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private AuthServerGetToken authServerGetToken;

    // ------------  密码模式 -----------------------------

    /**
     * 检查令牌是否有效，会有不同的返回值
     */
    @RequestMapping("/oauth2/check_token")
    public Object check(HttpServletRequest request) {
        return authServerResponse.check_token(request);
    }

    /**
     * 获取令牌信息，会有不同的返回值
     */
    @RequestMapping("/oauth2/info")
    public Object access(HttpServletRequest request, HttpServletResponse response) {
        try {
            return authServerResponse.info(request);
        } catch (Exception e) {
            authServerExceptionHandler.exception(e, request, response);
        }
        return null;
    }

    /**
     * 获取令牌权限，返回空时表示令牌无效，返回空数组：[] 令牌未设置权限，不代表token到期无效
     */
    @RequestMapping("/oauth2/authority")
    public Object authority(HttpServletRequest request) {
        return authServerResponse.authority(request);
    }

    /**
     * 登录或刷新令牌
     */
    @PostMapping("/oauth2/token")
    public Object token(HttpServletRequest request, HttpServletResponse response) {
        String grant_type = request.getParameter("grant_type");
        if (grant_type == null) {
            throw new AuthServerException("缺少参数 grant_type");
        }
        try {
            if ("password".equals(grant_type) || "refresh_token".equals(grant_type) || "authorization_code".equals(grant_type)) {
                return authorizationMode.token(request, response);
            }
        } catch (Exception e) {
            authServerExceptionHandler.exception(e, request, response);
        }
        return null;
    }

    /**
     * 注销token，连带刷新token一起被注销
     */
    @RequestMapping("/oauth2/logout")
    public Object logout(HttpServletRequest request) {
        String token = authServerGetToken.getToken(request);
        JSONObject res = new JSONObject();
        res.put("timestamp", System.currentTimeMillis());
        if (StringUtils.isEmpty(token)) {
            res.put("code", 1);
            res.put("msg", "无token参数！");
        } else {
            OAuth2AccessToken oAuth2AccessToken = tokenStore.removeAccessToken(token);
            if (oAuth2AccessToken != null) {
                tokenStore.removeRefreshToken(oAuth2AccessToken.getRefreshToken());
                res.put("code", 0);
                res.put("msg", "注销token成功！");
            } else {
                res.put("code", 1);
                res.put("msg", "无效的token, invalid token");
            }
        }
        return authServerResponse.logout(res);
    }


    // ---------- 授权码模式 -------------------
    @RequestMapping("/oauth2/authorize")
    public Object authorize(HttpServletRequest request, HttpServletResponse response) {
        String response_type = request.getParameter("response_type");
        JSONObject res = new JSONObject();
        if (StringUtils.isEmpty(response_type)) {
            res.put("code", 1);
            res.put("msg", "response_type 参数不能为空！");
            return res;
        }
        if ("code".equals(response_type)) {
            return authorizationMode.code(request, response);
        }
        return null;
    }
}
